CP-Snippets

Weird_Lazy_Segtree


// I can see a merge operation but not default values where to change, see build for more, change epsilon to something suitable for your operation like INF for min etc.
#include<bits/stdc++.h>

using namespace std;

#define all(x) begin(x), end(x)
#define sz(x) static_cast<int>((x).size())
#define int long long

const int INF = 1e18;

struct lazy {
        int val, lazyy;
};

struct SegtreeLazy {
        int size;
        vector<lazy> val;
        void init (int n) {
                size = 1;
                while (size < n) size *= 2;
                val.resize (2 * size - 1);
        }

        lazy merge (int x, int y) {
                return {min (val[x].val, val[y].val), 0};
        }        
        
        void propagate (int x) {
                val[2 * x + 1].val += val[x].lazyy;
                val[2 * x + 2].val += val[x].lazyy;
                val[2 * x + 1].lazyy += val[x].lazyy;
                val[2 * x + 2].lazyy += val[x].lazyy;
                val[x].lazyy = 0;
        }

        void build (vector<int> &a, int x, int lx, int rx) {
                if (rx - lx == 1) {
                        if (lx < sz(a)) val[x] = {a[lx], 0};
                        else val[x] = {INF, 0};
                        return;
                }
                int m = (lx + rx) / 2;
                build (a, 2 * x + 1, lx, m);
                build (a, 2 * x + 2, m, rx);
                val[x] = merge (2 * x + 1, 2 * x + 2);
        }

        void build (vector<int> &a) {
                build (a, 0, 0, size);
        }
        
        void RangeUpdate (int l, int r, int x, int lx, int rx, int v) {
                if (rx - lx == 1) {
                        val[x].val += v;
                        return;
                }
                if (lx >= l && rx <= r) {
                        val[x].val += v;
                        val[x].lazyy += v;
                        return;
                }
                int m = (lx + rx) / 2;
                propagate (x);
                if (m > l) {
                        RangeUpdate (l, r, 2 * x + 1, lx, m, v);
                }
                if (m < r) {
                        RangeUpdate (l, r, 2 * x + 2, m, rx, v);
                }
                val[x] = merge (2 * x + 1, 2 * x + 2);
                
        }

        void update (int l, int r, int v) {
                if (r <= l) return;
                RangeUpdate (l, r, 0, 0, size, v);
        }

        int get (int l, int r, int x, int lx, int rx) {
                if (rx - lx == 1) {
                        return val[x].val;
                }
                if (lx >= l && rx <= r) {
                        return val[x].val;
                }
                int m = (lx + rx) / 2;
                propagate (x);
                int a1 = INF, a2 = INF;
                if (m > l) {
                        a1 = get (l, r, 2 * x + 1, lx, m);
                }
                if (m < r) {
                        a2 = get (l, r, 2 * x + 2, m, rx);
                }
                return min (a1, a2);                
        }

        int get (int l, int r) {
                return get (l, r, 0, 0, size);
        }
        void out () {                
                for (int i = 0; i < sz(val); i++) cout << val[i].val << " " << val[i].lazyy << "  ";
        }

};
// EXAMPLE USAGE

// signed main() {

//         ios::sync_with_stdio(0);
//         cin.tie(0);
//         cout.tie(0);

//         int n, m;
//         cin >> n >> m;
//         vector<int> a(n);
//         for (auto &x : a) cin >> x;
//         int b[m];
//         for (auto &x : b) cin >> x;
//                                                     SegtreeLazy seg;
//                                                     seg.init(n);
//                                                     seg.build(a);  

//         for (auto i : b) {
//                 int x = seg.get(i, i + 1);
//                 int y = (i + 1) % n, z = (i + x) % n;
//                 if (y <= z) {
//                                                     seg.update(y, z + 1, 1);
//                 }
//                 else {
//                                                     seg.update(y, n, 1);
//                                                     seg.update(0, z + 1, 1);
//                 }
//                                                     seg.update(0, n, (x - 1) / n);
//                                                     seg.update(i, i + 1, -x);
//         }      

//         for (int i = 0; i < n; i++) cout <<         seg.get(i, i + 1) << " ";
        
// }